/**
    Copyright (c) 2010 yakiimo02
    Distributed under the New BSD License.
    See included license.txt or http://www.yakiimo3d.com/NewBSDLicense.txt
**/

#include "DXUT.h"
#include "GUI.h"
#include "LinkedListOIT.h"

GUI g_gui;

//--------------------------------------------------------------------------------------
// UI control IDs
//--------------------------------------------------------------------------------------
#define IDC_TOGGLEFULLSCREEN    1
#define IDC_TOGGLEREF           3
#define IDC_CHANGEDEVICE        4

#define IDC_BLEND_MODE_CB        10000

void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );

/**
*/
GUI::GUI() : m_pTxtHelper( NULL ), m_pBlendModeCB( NULL )
{
    m_bDisplayGUI = true;
}

/**
*/
HRESULT GUI::Create( ID3D11Device* pd3dDevice )
{
    HRESULT hr = S_OK;

    ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext();
    V_RETURN( m_DialogResourceManager.OnD3D11CreateDevice( pd3dDevice, pd3dImmediateContext ) );
    V_RETURN( m_D3DSettingsDlg.OnD3D11CreateDevice( pd3dDevice ) );
    m_pTxtHelper = new CDXUTTextHelper( pd3dDevice, pd3dImmediateContext, &m_DialogResourceManager, 15 );

     return hr;
}

/**
*/
void GUI::RegistGuiItems()
{
    m_SampleUI.Init( &m_DialogResourceManager );
    m_SampleUI.SetCallback( OnGUIEvent ); 

    m_D3DSettingsDlg.Init( &m_DialogResourceManager );
    m_HUD.Init( &m_DialogResourceManager );
    m_SampleUI.Init( &m_DialogResourceManager );

    // mode combobox
    int nY = 0;

    m_SampleUI.AddComboBox( IDC_BLEND_MODE_CB, 0, nY, 150, 24, 'M', false, &m_pBlendModeCB );
    m_pBlendModeCB->AddItem( L"Regular", IntToPtr(BLEND_REGULAR) );
    m_pBlendModeCB->AddItem( L"OIT", IntToPtr(BLEND_OIT) );
    m_pBlendModeCB->SetSelectedByIndex( g_linkedListOIT.GetBlendMode() );
    m_pBlendModeCB->SetTextColor( D3DCOLOR_XRGB( 0, 0, 255 ) );
    nY += 24;

    m_HUD.SetCallback( OnGUIEvent ); int iY = 20;
    m_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 0, iY, 170, 23 );
    m_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 0, iY += 26, 170, 23, VK_F3 );
    m_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 0, iY += 26, 170, 23, VK_F2 );

    m_SampleUI.SetCallback( OnGUIEvent ); 
}

/**
*/
bool GUI::FrameRender( float fElapsedTime )
{
    // If the settings dialog is being shown, then render it instead of rendering the app's scene
    if( m_D3DSettingsDlg.IsActive() )
    {
        m_D3DSettingsDlg.OnRender( fElapsedTime );
        return true;
    }

    if( m_bDisplayGUI ) 
    {
        DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" );
        m_HUD.OnRender( fElapsedTime );
        m_SampleUI.OnRender( fElapsedTime );
        RenderText();
        DXUT_EndPerfEvent();
    }

    return false;
}

/**
*/
void GUI::RenderText()
{
    m_pTxtHelper->Begin();
    m_pTxtHelper->SetInsertionPos( 2, 0 );
    m_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1.0f ) );
    m_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) );
    m_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );

    wchar_t strMsg[ 256 ];
    swprintf_s( strMsg, L"Translate Cam: WASD, Rotate Cam: LMB, Hide GUI: H key" );
    m_pTxtHelper->DrawTextLine( strMsg );

    m_pTxtHelper->End();
}

/**
*/
HRESULT GUI::ResizedSwapChain( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc )
{
    HRESULT hr = S_OK;

    V_RETURN( m_DialogResourceManager.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) );
    V_RETURN( m_D3DSettingsDlg.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) );

    m_HUD.SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 );
    m_HUD.SetSize( 170, 170 );
    m_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 350 );
    m_SampleUI.SetSize( 170, 300 );

    return hr;
}

/**
*/
void GUI::Destroy()
{
    m_DialogResourceManager.OnD3D11DestroyDevice();
    m_D3DSettingsDlg.OnD3D11DestroyDevice();
    SAFE_DELETE( m_pTxtHelper );    
}

/**
*/
void GUI::ReleasingSwapChain()
{
    m_DialogResourceManager.OnD3D11ReleasingSwapChain();
}

/**
*/
LRESULT GUI::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing )
{
    // Pass messages to dialog resource manager calls so GUI state is updated correctly
    *pbNoFurtherProcessing = m_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing )
        return 0;

    // Pass messages to settings dialog if its active
    if( m_D3DSettingsDlg.IsActive() )
    {
        m_D3DSettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
        return 0;
    }

    // Give the dialogs a chance to handle the message first
    *pbNoFurtherProcessing = m_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing )
        return 0;
    *pbNoFurtherProcessing = m_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing )
        return 0;

    return 0;
}

/**
    CDXUTDialog callback.
*/
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
{
    CD3DSettingsDlg& settingsDlg = g_gui.GetrSettingsDlg();
    

    switch( nControlID )
    {
    case IDC_TOGGLEFULLSCREEN:
        DXUTToggleFullScreen(); 
        break;
    case IDC_TOGGLEREF:
        DXUTToggleREF(); 
        break;
    case IDC_CHANGEDEVICE:
        settingsDlg.SetActive( !settingsDlg.IsActive() ); 
        break;

    case IDC_BLEND_MODE_CB:
        {
            CDXUTComboBox* pComboBox = ( CDXUTComboBox* )pControl;
            g_linkedListOIT.SetBlendMode( static_cast< BlendMode >( PtrToInt( pComboBox->GetSelectedData() ) ) );
            break;
        }
    }
}
